// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

#ifndef _INT2_H_
#define _INT2_H_

#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
\file
\ingroup	gio
\brief		SNP 2-way interaction */

/*!
\brief	Structure representing a 2-way interaction between 2 SNPs
\details Data-type primarily used by the epistasis codes. */
struct INT2 {
  /*! \brief Array index of the 1st SNP in the interation.  */  
  int p1;

  /*! \brief Array index of the 2nd SNP in the interation.  */  
  int p2;

  /*! \brief The Z-score utilised by a CHISQ function to calculate interaction probability. */  
  double z;

  /*! \brief Coefficient value (needed by pepi_qt). */  
  double coeff;

  /*! \brief The number of valid interactions occurring in 'N' permutations. */  
  int nPermutations;

  /*! \brief Counter variable to calculate the randomised empirical p-value (EMP1). */  
  int R;

  /*! \brief Counter variable to calculate the Family Wide Error (FWE/EMP2). */  
  int maxR;

  /*! \brief Flag if interaction is valid, i.e. generated a test statistic and any associated variables. */  
  BOOL valid;
};

/*! 
\brief Initialises a INT2 structure.
\details Zeros all bound numeric fields and sets all bound boolean fields to FALSE.
\param [in, out] i Pointer to an INT2 structure
*/
void int2_init(struct INT2 *i);

/*!
\brief QSORT comparator function for array sorting.
\details 
	Array sorted in by indices of the INT2::p1 and INT2::p2 which 
	reference positions in an input SNP array.
\param[in] p1 Pointer to INT2 structure
\param[in] p2 Pointer to INT2 structure
\returns integer (-1 if p1 < p2, 0 if p1 == p2, 1 if p1 > p2)
*/
int int2_cmp(const void* p1, const void* p2);

/*!
\brief Echo INT2 structure to STDOUT. 
\param[in] i2 Pointer to INT2 structure
*/
void int2_echo(struct INT2 *i2);

/*! 
\brief Load an INT2 array from a binary file.
\details 
	An INT2 file usually contains <em>interesting interactions</em>
	identified by a p-value thresholds (typically P <= 0.05).
	The contents of the array may be unsorted depending on the program generating the file.
	Input files have normally the suffix \ref SUFFIX_EPI_FILE2 .
\param [in] filepath Binary INT2 file to load
\param [in, out] nNumberRead No. elements in the INT2 returned by the function.
\returns Array of INT2 (or NULL on failure)
*/
struct INT2* int2_load(char *filepath, int *nNumberRead);

/*!
\brief Finds an INT2 element in an larger array and returns the array index.
\details
	Uses the binary search algorithm to find an 'interesting interaction' 
	from a larger interaction. The array must be sorted prior to searching.
\param [in] a Array to search
\param [in] nA Size of the array to search
\param [in] *x Pointer to the element to find in the array
\return Index of x in the array (or -1 on failure).
*/
int int2_search(struct INT2 *a, int nA, struct INT2 *x);

/*! 
\brief Sets the valid flags of elements in the array to \ref FALSE. 
\param [in, out] a The array
\param [in] nA Size of the array.
\see INT2::valid
*/
void int2_reset_valid(struct INT2 *a, int nA);

#ifdef __cplusplus
}
#endif

#endif // _INT2_H_
